#include "cvector2d.h"

/**
 * CVector2D - constructor
 */
template <typename T>
CVector2D<T>::CVector2D() {
  this->init(this->VECTOR_SPACE_2D);
}
//---------------------------------------------------------------------------

/**
 * CVector2D - constructor, sets vector items
 * @param x
 * @param y
 */
template <typename T>
CVector2D<T>::CVector2D(T x, T y) {
  this->init(this->VECTOR_SPACE_2D);
  setX(x);
  setY(y);
}
//---------------------------------------------------------------------------

/**
 * CVector2D - copy constructor
 * @param v
 */
template <typename T>
CVector2D<T>::CVector2D(const CVector2D<T> &v) {
  this->copyFrom(v);
}
//---------------------------------------------------------------------------

/**
 * CVector2D - copy constructor
 * @param v
 */
template <typename T>
CVector2D<T>::CVector2D(const CVectorBase<T> &v) {

  // If given vector does not have matching number of items, throw exception
  if (v.getSize() != this->VECTOR_SPACE_2D) {
    throw CInvalidSizeException(getClassName(), "CVector2D");
  }
  this->copyFrom(v);
}
//---------------------------------------------------------------------------

/**
 * ~CVector2D - destructor, free vector from memory
 */
template <typename T>
CVector2D<T>::~CVector2D() {
  this->free();
}
//---------------------------------------------------------------------------

/**
 * operator= - assign (copy) vector
 * @param v
 * @return this
 */
template <typename T>
CVector2D<T>& CVector2D<T>::operator = (const CVector2D<T> &v) {

  // Uvolneni pamet, provede okopirovani, a vrati vysledek (tranzitivita)
  this->free();
  this->copyFrom(v);
  return *this;
}
//---------------------------------------------------------------------------

/**
 * operator+ - sum of vectors
 * @param v
 * @return sum
 */
template <typename T>
CVector2D<T> CVector2D<T>::operator + (const CVector2D<T> &v) const {
  return CVector2D<T>(*this) += v;
}
//---------------------------------------------------------------------------

/**
 * operator- - difference of vectors
 * @param v
 * @return difference
 */
template <typename T>
CVector2D<T> CVector2D<T>::operator - (const CVector2D<T> &v) const {
  return CVector2D<T>(*this) -= v;
}
//---------------------------------------------------------------------------

/**
 * operator* - multiplies vector by number
 * @param num
 * @return multiplied vector
 */
template <typename T>
CVector2D<T> CVector2D<T>::operator * (T num) const {
  return CVector2D<T>(*this) *= num;
}
//---------------------------------------------------------------------------

/**
 * operator/ - divides vector by number
 * @param num
 * @return divided vector
 */
template <typename T>
CVector2D<T> CVector2D<T>::operator / (T num) const {
  return CVector2D<T>(*this) /= num;
}
//---------------------------------------------------------------------------

/**
 * getSize - vrati velikost (pocet slozek) vektoru
 * @return pocet slozek vektoru
 */
template <typename T>
TIndex CVector2D<T>::getSize() const {
  return this->VECTOR_SPACE_2D;
}
//---------------------------------------------------------------------------

/**
 * getX - returns x axis position
 * @return x axis position
 */
template <typename T>
T CVector2D<T>::getX() const {
  return this->items[0];
}
//---------------------------------------------------------------------------

/**
 * getY - returns y axis position
 * @return y axis position
 */
template <typename T>
T CVector2D<T>::getY() const {
  return this->items[1];
}
//---------------------------------------------------------------------------

/**
 * setX - sets x axis position
 * @param x
 */
template <typename T>
void CVector2D<T>::setX(T x) {
  this->items[0] = x;
}
//---------------------------------------------------------------------------

/**
 * setY - sets y axis position
 * @param y
 */
template <typename T>
void CVector2D<T>::setY(T y) {
  this->items[1] = y;
}
//---------------------------------------------------------------------------

/**
 * setSize - disables parent class method
 * @param size
 */
template <typename T>
void CVector2D<T>::setSize(TIndex size) {}
//---------------------------------------------------------------------------

template class CVector2D<char>;
template class CVector2D<unsigned char>;
template class CVector2D<short>;
template class CVector2D<unsigned short>;
template class CVector2D<int>;
template class CVector2D<unsigned int>;
template class CVector2D<long>;
template class CVector2D<unsigned long>;
template class CVector2D<float>;
template class CVector2D<double>;
template class CVector2D<CBigInt>;
template class CVector2D<CFraction>;
